#!/usr/bin/python2
#coding:utf8

import os
import binascii
import signal
import errno

from utils import _dmsg, _dwarn, _derror, _check_config, Exp, _check_crontab, \
            _get_network, _get_speed, _aton, _exec_system, _hostname2ip, _set_value, _exec_shell1

class Ucarp:
    def __init__(self, node):
        self.node = node
        self.config = node.config
        self.vip_up = "/etc/vip-up.sh"
        self.vip_down = "/etc/vip-down.sh"

    def init(self):
        if not self.config.is_ucarpconfd():
            return

        lich_network = self.config.get_lich_network()
        if len(lich_network) != 1:
            raise Exp(errno.ENOENT, "network config error, please check lich.conf or ip addr")

        eth = lich_network.keys()[0]
        vip = self.config.ucarp_vip

        #generate /etc/vip-up.sh
        content = '''#!/bin/bash
ip addr add %s dev %s
arping  -c 5 -U -I %s %s
''' % (vip, eth, eth, vip.split('/')[0])
        _set_value(self.vip_up, content)
        os.chmod(self.vip_up, 0755)

        #generate /etc/vip-down.sh
        content = '''#!/bin/bash
ip addr del %s dev %s
''' % (vip, eth)
        _set_value(self.vip_down, content)
        os.chmod(self.vip_down, 0755)

    def start(self):
        if not self.config.is_ucarpconfd():
            self.destroy()
            return

        lich_network = self.config.get_lich_network()
        if len(lich_network) != 1:
            raise Exp(errno.ENOENT, "network config error, please check lich.conf or ip addr")

        pids = self.pid_find()
        if len(pids) != 0:
            self.stop()

        eth = lich_network.keys()[0]
        srcip = lich_network.values()[0][0]
        addr = self.config.ucarp_vip.split('/')[0]

        # --vhid=<id> (-v <id>): virtual IP identifier (1-255)
        # notes:May be repeated!
        vhid = binascii.crc32(self.config.getclusteruuid()) % 255 + 1

        '''
        ucarp --interface=eth0 --srcip=10.1.1.1 --vhid=1 --pass=mypassword \
                --addr=10.1.1.252 \
                --upscript=/etc/vip-up.sh --downscript=/etc/vip-down.sh
        '''
        cmd = """ucarp --interface=%s --srcip=%s --addr=%s --vhid=%s --pass=mdsmds --upscript=%s --downscript=%s -B""" \
                % (eth, srcip, addr, vhid, self.vip_up, self.vip_down)

        _exec_shell1(cmd)

    def pid_find_psutil(self):
        import psutil

        pids = []
        for pid in psutil.get_pid_list():
            p = psutil.Process(pid)
            if p.name == "ucarp":
                pids.append(pid)

        return pids

    def pid_find_ps(self):
        cmd  = "ps -ef | grep 'ucarp .* --pass=mdsmds' | grep -v 'grep' | awk '{print $2}'"
        res, err = _exec_shell1(cmd, p=False)

        if res.strip() == "":
            return []
        return [int(x) for x in res.split()]

    def pid_find(self):
        return self.pid_find_ps()

    def stop(self):
        if not self.config.is_ucarpconfd():
            self.destroy()
            return

        lich_network = self.config.get_lich_network()
        if len(lich_network) != 1:
            raise Exp(errno.ENOENT, "network config error, please check lich.conf or ip addr")

        eth = lich_network.keys()[0]
        vip = self.config.ucarp_vip

        pids = self.pid_find()
        for pid in pids:
            os.kill(pid, signal.SIGKILL)

        _exec_system(self.vip_down, False, False, False)

    def destroy(self):
        pids = self.pid_find()
        for pid in pids:
            os.kill(pid, signal.SIGKILL)

        if os.path.exists(self.vip_down):
            _exec_system(self.vip_down, False, False, False)
        if os.path.exists(self.vip_up):
            os.unlink(self.vip_up)
        if os.path.exists(self.vip_down):
            os.unlink(self.vip_down)

    def check(self):
        if not self.config.is_ucarpconfd():
            self.destroy()
            return

        lich_network = self.config.get_lich_network()
        if len(lich_network) != 1:
            raise Exp(errno.ENOENT, "network config error, please check lich.conf or ip addr")

        instance = self.node.instences[0]
        if instance.running():
            pids = self.pid_find()
            if len(pids) == 0:
                self.start()
        else:
            pids = self.pid_find()
            if len(pids) != 0:
                self.stop()

    def show(self):
        if not self.config.is_ucarpconfd():
            self.destroy()
            return

        cmd = "ip addr show | grep %s > /dev/null" % self.config.ucarp_vip
        is_vip = _exec_system(cmd, False) == 0
        pids = self.pid_find()
        if len(pids) != 0:
            if is_vip:
                print "running, %s" % self.config.ucarp_vip
            else:
                print "running"
        else:
            if is_vip:
                print "stopped, %s" % self.config.ucarp_vip
            else:
                print "stopped"

    def test(self):
        pids = self.pid_find()
        print "pid ,", pids
